Exploratory Data Analysis and Visualizations (STAT GR5702)

PART I

Problem 1: Occupational Mobility

Source: Chapter 4, p. 73 no. 5

According to R help page, the Yamaguchi87 dataset in vcdExtra has become a classic for models comparing two-way mobility tables. Note that this package contains a frequency data frame with 75 observations on the following 4 variables. The total sample size is 28,887.

library(ggplot2)
library(vcdExtra)
library(magrittr)
library(knitr)
library(dplyr)
library(tidyr)
# Open and read the data
data(Yamaguchi87)
y <<- data.frame(Yamaguchi87)
a) How do the distribution of occupations of the sons in the three countries compare?

According to the overall plot of the distribution of occupations of the sons below, the number of jobs are highest in US compared to UK or Japan in all occupation areas, including those categorized as Upper NonManuals (UpNM), Lower NonManuals (LoNM), Upper Manuals (UpM), Lower Manuals (LoNM), and Farming (Farm). The opportunity for the son’s jobs seems to be the highest in US, followed by UK then Japan.

By observing the distribution by occupations shown in the following paragraph, all categories but Farm actually shares very similar pattern, that US has the highest number of occupations, followed by UK, then Japan. Upper nonmanuals are professionals, managers, and officials; lower nonmanuals are proprietors, sales workers, and clerical workers; upper manuals are skilled workers; lower manuals are semiskilled and unskilled nonfarm workers; and farm workers are farmers and farm laborers. For the last category, US still has the highest number of jobs but UK comes to be the least among the three country.

# Distribution plot by occupation
ggplot(y,aes(x=Country,y=Freq,fill=Son)) + geom_bar(stat="identity") + 
  ggtitle("Distributions by Occupations of the Sons in US, UK, and Japan") + ylab("Frequency") + xlab("Country") +
  facet_grid( . ~ Son) +guides(fill=FALSE)

b) How do the distributions of the sons’ and fathers’ occupations in the UK compare?

To compare the occupation distributions between sons and fathers, I plotted a side-by-side frequency graph by occupation in an ascending order below. It follows that nonmanual works are more dominant among the sons (e.g. Sons have higher frequency for UpNM and LoNM), while the fathers have higher number of occupations in upper and lower manuals and farming jobs.

c) Are you surprised by the results or are they what you would have expected?

I am not quite surprised by the results. I would expect US to have the highest frequency on both the father and son occupations compared to UK or Japan. A reason for this is the population factor. I also expected a similar pattern for occupation distribution in UK across all job categories between the fathers and the sons. Younger generations tend to have better lives and more opportunities statistically, where most parents want to set out better paths for their children. It is definitely more common to encounter fathers with manual or farming job and sons with nonmanual labors.


Problem 2: Whisky

Source: Chapter 4, p. 73 no. 6 from Simmons Survey. The Whisky file contains a data frame with 2,218 observations on the following 21 variables. All variables are coded 1 if consumed in last year, 0 if not.

a) Draw a barchart of the number of respondents per brand. What ordering of the brands do you think is best?

The following graph shows the frequency of brands used in last year for the respondents who report consuming scotch. We see that scotch Chivas Regal was reported to be the most consumed, and Singleton was the least consumed.



In order to see the distribution more clearly, it would be best to sort the brand in the descending order by its frequency of use. In this case, Chivas Regal would be on the top and the Singleton would be at the very bottom of the graph.

b) There are 20 named brands and a further category Other.brands. Plot a chart containing big brands and grouping smaller brand names to “Other” brand. What cutoff would you use for defining a big brand?

According to the ordered graph in (a), we see that the frequency drops significantly after Glenfiddich brand. That is, from over 300 to a little over 100. This would therefore be a good cutoff point (e.g. 300) for grouping those with frequency less than that of Glenfiddich scotch to brand “Other”.

c) Two other dataset versions are called whiskey and whiskey_brands. How do you incorporate this information in your graphics? By using a different ordering, a colour, or drawing two graphics rather than one?

To incorporate this both whiskey and whiskey_brands in one graphic, I would add both Incidence and Freq and then plot it with different coloring and stack them on top of each other. After trying out different graphs, I chose to incorporate it this way because the graph looks informative and involves both ordering and colors. For instance, in the following graph we can see different types (Blend v. Single Malt) and origins of various whiskey brands (places as a legend).

The data set is from Simmons Study of Media and Markets and contains the incidence matrix for scotch brands used in last year for those households who report consuming scotch.

d) Which spellings, ‘whisky’ or ‘whiskey’ is more appropriate?

The spelling whisky is generally used for whiskies distilled in Scotland, Canada, Australia, Japan and Europe, while whiskey is used for the spirits distilled in Ireland and America. In this case, since many of these brands come from Scotland, it would be more appropriate to use whisky than whiskey.

#### Problem 3: Olive Oils from Italy Source: Chapter 5, p. 97 no. 8 Various fatty acid measurements. A data frame with 572 observations.
#####a) Draw a default parallel coordinate plot and describe various features you can see. From the graph below, you can see that there are 11 variables of the olive dataset, containing eicosenoic, arachidic, linolenic, linoleic, and so on. These features correlate to each other in within their region: noth, south or sardinia. ..
#####b) Draw the same plot and color the oils by the region they come from. What additional information can you find? Palmitic and palmitoleic are positively correlated to each other. Oleic is negatively correlated with palmitic, palmitoleic and linoleic.
#####c) Discuss which features of the dataset are easier to see with a PCP plot and which are easier to see with a scatterplot matrix? It is easier to see in scatterplot matrix than PCP, as we can see outliers and significance of each variable more clearly. Cluster groups and the diagonal matrices help identify better the correlation between one variable to another. It is a little harder to see using PCP since the ordering becomes more sensible. However, we see that there may be some subgroup of classes within PCP that would be an advantage over scatterplot.

Problem 4: Hertzsprung-Russell

Source: Chapter 5, p. 97 no. 10 Data for the Hertzsprung-Russell Diagram of the Star Cluster CYG OB1, which contains 47 stars in the direction of Cygnus, from C.Doom. The first variable is the logarithm of the effective temperature at the surface of the star (Te) and the second one is the logarithm of its light intencity (L/L0).
A data frame with 47 observations on the following 2 variables log.Te Logarithm of the effective temperature at the surface of the star (Te). log.light Logarithm of its light intencity (L/L0).

a) Plot Y against X. How does the plot differ from the plots you find on the web, for instance from a google search for images of this diagram?

The plot below shows that Hertzsprung-Russell diagrams plot star luminosity (brightness) against temperature (colour). The first one was drawn just over 100 years ago, based on dataset from the Yale Trigonometric Parallax.



HR Scatterplot resembles the graphic found on google better compared to that of StarsCYG. This makes sense because there are more datapoints shown in the diagram. In the Hertzsprung-Russell diagram, which is the scatterplot of these data points, where the log temperature is plotted from left to right, two groups of points are seen: the majority which tend to follow a steep band and four stars in the upper corner. In the astronomy the 43 stars are said to lie on the main sequence and the four remaining stars are called “giants” (the points 11, 20, 30, 34).

b) The plots seem to use different numbers of stars. Are some more likely to be used than others?

Yes. There are plots with less points showing the composition but there are also other plots with more points that show exact situations.

c) Any suggestions?

After reading a few notes from Chapter 13, I would want to base my coloring on the BV index. This way, the diagram would have more contrast, hues and saturation. I would also manipulate datapoints on the graph for clustering purposes, which would trigger identifying patterns and conclusion from the data (an example is the Super Giants cluster name).


Problem 5: Bodyfat

Source: Chapter 6, p. 130 no. 5 Dataset bodyfat provides estimates of the percentage of body fat of 252 men, determined by underwater weighing and body circumference measurements. Draw a parallel coordinate plot for the dataset.

a) Are there any outliers? What can you say about them?

Yes, there are certainly outliers. We can see from the plot that some lines do not follow the normal aggregated lines in the middle. For instace, some have points in 1.00 value when majority of lines are close to 0.25 for ankle category. We can also see from the following PCP plot that is ordered, some lines are off the flow, for instance the green lines in the upper part, which also confirm our claim about existing outliers.

b) Can you deduce anything about the height variable?

Specifically for the height variable, the range is wide, meaning that data ranges from the lowest to the highest value (from 0 to 1). It also suggests that those who are older with higher bodyfat tend to be shorter and those who are younger with low bodyfat tend to be taller. We can also derive from this conclusion and through the plot that the height variable is directly related to age.

c) What can you say about the relationship between the first two variables: density and bodyfat?

Looking at the following graph, the density variable is inversely proportional to the bodyfat variable, within the range of 0.0 and 1.0. In this case, when density is 1.0, bodyfat would be 0.0. To make sense of this we can think of bones that are very heavy, which would not have any fat.

d) Do you think the ordering of the variables is sensibile? What alternative orderings might be informative?

Yes, the ordering of variables is sensible. We can see from the above plot that when paired or compared side by side, two variables in PCP plots can show strong correlation, for instance in the case for density and bodyfat. An alternative orderings that might be informative is splitting it into age groups, as shown below. By flipping the axis and observing through different age groups, we can also see how bodyparts correlate to one another in their order. All age groups seem to share similar pattern.


Problem 6: Wine

Source: Chapter 6, p. 130 no. 7 The wine dataset contains data of three classes of wine. #####a) Use PCP to investigate how well the variables separate these classes. Variable data across classes are pretty consistent. Blue lines (class)

library(pgmm)
library(gclus)
library(rattle)

rm(list=ls())
data(wine)
# wine <- as.data.frame(wine)
ggparcoord(wine, columns = c(1:13), scale = "uniminmax",
           groupColumn = "class")+
  geom_line(alpha=0.21)+
  facet_wrap(~class, ncol = 1)+
  ggtitle("Wine Characteristic by Class")+
  theme(plot.title=element_text(hjust=0.5),
        panel.background = element_rect(fill = "lightgray"))+
  xlab("Wine Characteristic") + 
  ylab("Value")+
  coord_flip()

b) Are there any outliers?

Yes, by observing the graph above we see that there are some outliers within each class, Barbera, Barolo and Grignolino. However, data look very consistent and hence outliers would not affect the dataset as much. We see that data points in Grignolino has more outliers than Barbera or Barolo.

c) Is there evidence of subgroups within the classes?

We can perhaps say that there are subgroups within these classes. For instance, the very tight lines among different classes suggest their same exact patterns and behaviors. However, there are some lines that do not follow certain flow as the other (e.g. slopes are negative when a subclass shows an increasing line or positive slope), but they are not outliers as well because there are many of them that behave very similarly. In this case, we can call there are a few subgroups within the classes.


PART II

Choose two datasets from the above exercises. For each, provide insight, through graphs and text, on an issue that goes beyond those discussed in the homework exercises. Any type of graph is permitted, whether or not covered in class, so you may take this as an opportunity to explore new options.

cols <- c("orange", "red", "green")
cols <- c("orange", "red", "green")
ggplot(d,aes(x=arachidic,y=stearic, colour= Region, size=3))+geom_point()+
  facet_wrap(~Area)+ ggtitle("Scatterplot by Areas")+ theme(plot.title=element_text(hjust=0.5))
Warning in gzfile(file, "wb") :
  cannot open compressed file '/Users/Moorissa/.rstudio-desktop/notebooks/EB6F89F5-HW02-mmt2167/1/D3612B7D/c10gmxubuxe9n_t/5112663be6db46338aa8751b7d68caf1.snapshot', probable reason 'No such file or directory'
Error in gzfile(file, "wb") : cannot open the connection
Error in (function (which = dev.cur())  : 
  QuartzBitmap_Output - unable to open file '/Users/Moorissa/.rstudio-desktop/notebooks/EB6F89F5-HW02-mmt2167/1/D3612B7D/c10gmxubuxe9n_t/_rs_chunk_plot_001.png'


I always like stacked bar charts since it shows an overall sum of frequencies of different groups. Taking the first problem in another approach, I’d like to see the overall plot of the distribution of occupations of the sons above, the number of jobs are highest in US compared to UK or Japan in all occupation areas, including those categorized as Upper NonManuals (UpNM), Lower NonManuals (LoNM), Upper Manuals (UpM), Lower Manuals (LoNM), and Farming (Farm). This confirms our claim in the first problem that the opportunity for the son’s jobs seems to be the highest in US, followed by UK then Japan.

LS0tCnRpdGxlOiAiSFcgMDIiCmF1dGhvcjogIk1vb3Jpc3NhIFRqb2tybyAobW10MjE2NykiCm91dHB1dDoKICBodG1sX25vdGVib29rOiBkZWZhdWx0Ci0tLQojIyBFeHBsb3JhdG9yeSBEYXRhIEFuYWx5c2lzIGFuZCBWaXN1YWxpemF0aW9ucyAoU1RBVCBHUjU3MDIpCgojIyMgUEFSVCBJCgojIyMjIFByb2JsZW0gMTogT2NjdXBhdGlvbmFsIE1vYmlsaXR5CipTb3VyY2U6IENoYXB0ZXIgNCwgcC4gNzMgbm8uIDUqICAKICAKQWNjb3JkaW5nIHRvIFIgaGVscCBwYWdlLCB0aGUgWWFtYWd1Y2hpODcgZGF0YXNldCBpbiB2Y2RFeHRyYSBoYXMgYmVjb21lIGEgY2xhc3NpYyBmb3IgbW9kZWxzIGNvbXBhcmluZyB0d28td2F5IG1vYmlsaXR5IHRhYmxlcy4gTm90ZSB0aGF0IHRoaXMgcGFja2FnZSBjb250YWlucyBhIGZyZXF1ZW5jeSBkYXRhIGZyYW1lIHdpdGggNzUgb2JzZXJ2YXRpb25zIG9uIHRoZSBmb2xsb3dpbmcgNCB2YXJpYWJsZXMuIFRoZSB0b3RhbCBzYW1wbGUgc2l6ZSBpcyAyOCw4ODcuICAKICAgCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQpsaWJyYXJ5KGdncGxvdDIpCmxpYnJhcnkodmNkRXh0cmEpCmxpYnJhcnkobWFncml0dHIpCmxpYnJhcnkoa25pdHIpCmxpYnJhcnkoZHBseXIpCmxpYnJhcnkodGlkeXIpCgojIE9wZW4gYW5kIHJlYWQgdGhlIGRhdGEKZGF0YShZYW1hZ3VjaGk4NykKeSA8PC0gZGF0YS5mcmFtZShZYW1hZ3VjaGk4NykKYGBgCiAgIAogICAKIyMjIyNhKSBIb3cgZG8gdGhlIGRpc3RyaWJ1dGlvbiBvZiBvY2N1cGF0aW9ucyBvZiB0aGUgc29ucyBpbiB0aGUgdGhyZWUgY291bnRyaWVzIGNvbXBhcmU/ICAKICAgCkFjY29yZGluZyB0byB0aGUgb3ZlcmFsbCBwbG90IG9mIHRoZSBkaXN0cmlidXRpb24gb2Ygb2NjdXBhdGlvbnMgb2YgdGhlIHNvbnMgYmVsb3csIHRoZSBudW1iZXIgb2Ygam9icyBhcmUgaGlnaGVzdCBpbiBVUyBjb21wYXJlZCB0byBVSyBvciBKYXBhbiBpbiBhbGwgb2NjdXBhdGlvbiBhcmVhcywgaW5jbHVkaW5nIHRob3NlIGNhdGVnb3JpemVkIGFzIFVwcGVyIE5vbk1hbnVhbHMgKFVwTk0pLCBMb3dlciBOb25NYW51YWxzIChMb05NKSwgVXBwZXIgTWFudWFscyAoVXBNKSwgTG93ZXIgTWFudWFscyAoTG9OTSksIGFuZCBGYXJtaW5nIChGYXJtKS4gVGhlIG9wcG9ydHVuaXR5IGZvciB0aGUgc29uJ3Mgam9icyBzZWVtcyB0byBiZSB0aGUgaGlnaGVzdCBpbiBVUywgZm9sbG93ZWQgYnkgVUsgdGhlbiBKYXBhbi5cClwKQnkgb2JzZXJ2aW5nIHRoZSBkaXN0cmlidXRpb24gYnkgb2NjdXBhdGlvbnMgc2hvd24gaW4gdGhlIGZvbGxvd2luZyBwYXJhZ3JhcGgsIGFsbCBjYXRlZ29yaWVzIGJ1dCBGYXJtIGFjdHVhbGx5IHNoYXJlcyB2ZXJ5IHNpbWlsYXIgcGF0dGVybiwgdGhhdCBVUyBoYXMgdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIG9jY3VwYXRpb25zLCBmb2xsb3dlZCBieSBVSywgdGhlbiBKYXBhbi4gVXBwZXIgbm9ubWFudWFscyBhcmUgcHJvZmVzc2lvbmFscywgbWFuYWdlcnMsIGFuZCBvZmZpY2lhbHM7IGxvd2VyIG5vbm1hbnVhbHMgYXJlIHByb3ByaWV0b3JzLCBzYWxlcyB3b3JrZXJzLCBhbmQgY2xlcmljYWwgd29ya2VyczsgdXBwZXIgbWFudWFscyBhcmUgc2tpbGxlZCB3b3JrZXJzOyBsb3dlciBtYW51YWxzIGFyZSBzZW1pc2tpbGxlZCBhbmQgdW5za2lsbGVkIG5vbmZhcm0gd29ya2VyczsgYW5kIGZhcm0gd29ya2VycyBhcmUgZmFybWVycyBhbmQgZmFybSBsYWJvcmVycy4gRm9yIHRoZSBsYXN0IGNhdGVnb3J5LCBVUyBzdGlsbCBoYXMgdGhlIGhpZ2hlc3QgbnVtYmVyIG9mIGpvYnMgYnV0IFVLIGNvbWVzIHRvIGJlIHRoZSBsZWFzdCBhbW9uZyB0aGUgdGhyZWUgY291bnRyeS4gCgpgYGB7cn0KIyBEaXN0cmlidXRpb24gcGxvdCBieSBvY2N1cGF0aW9uCmdncGxvdCh5LGFlcyh4PUNvdW50cnkseT1GcmVxLGZpbGw9U29uKSkgKyBnZW9tX2JhcihzdGF0PSJpZGVudGl0eSIpICsgCiAgZ2d0aXRsZSgiRGlzdHJpYnV0aW9ucyBieSBPY2N1cGF0aW9ucyBvZiB0aGUgU29ucyBpbiBVUywgVUssIGFuZCBKYXBhbiIpICsgeWxhYigiRnJlcXVlbmN5IikgKyB4bGFiKCJDb3VudHJ5IikgKwogIGZhY2V0X2dyaWQoIC4gfiBTb24pICtndWlkZXMoZmlsbD1GQUxTRSkKYGBgCiAgCiAgIAojIyMjI2IpIEhvdyBkbyB0aGUgZGlzdHJpYnV0aW9ucyBvZiB0aGUgc29ucycgYW5kIGZhdGhlcnMnIG9jY3VwYXRpb25zIGluIHRoZSBVSyBjb21wYXJlPyAgCiAgIApUbyBjb21wYXJlIHRoZSBvY2N1cGF0aW9uIGRpc3RyaWJ1dGlvbnMgYmV0d2VlbiBzb25zIGFuZCBmYXRoZXJzLCBJIHBsb3R0ZWQgYSBzaWRlLWJ5LXNpZGUgZnJlcXVlbmN5IGdyYXBoIGJ5IG9jY3VwYXRpb24gaW4gYW4gYXNjZW5kaW5nIG9yZGVyIGJlbG93LiBJdCBmb2xsb3dzIHRoYXQgbm9ubWFudWFsIHdvcmtzIGFyZSBtb3JlIGRvbWluYW50IGFtb25nIHRoZSBzb25zIChlLmcuIFNvbnMgaGF2ZSBoaWdoZXIgZnJlcXVlbmN5IGZvciBVcE5NIGFuZCBMb05NKSwgd2hpbGUgdGhlIGZhdGhlcnMgaGF2ZSBoaWdoZXIgbnVtYmVyIG9mIG9jY3VwYXRpb25zIGluIHVwcGVyIGFuZCBsb3dlciBtYW51YWxzIGFuZCBmYXJtaW5nIGpvYnMuIApgYGB7cn0KbWRhdGEgPC0gZ2F0aGVyKHksIEZhbWlseSwgdmFsdWUsIFNvbjpGYXRoZXIpJT4lZmlsdGVyKENvdW50cnkgPT0gIlVLIikKZ2dwbG90KG1kYXRhLCBhZXMoeCA9IHJlb3JkZXIodmFsdWUsIEZyZXEpLCB5PUZyZXEpKSArIAogIGdlb21fY29sKGFlcyhmaWxsPUZhbWlseSkpICsKICBmYWNldF93cmFwKH5GYW1pbHkpICsKICBnZ3RpdGxlKCJPY2N1cGF0aW9uIERpc3RyaWJ1dGlvbnMgb2YgU29ucyBhbmQgRmF0aGVycyBpbiBVSyIpICsgCiAgeGxhYigiT2NjdXBhdGlvbiIpICsKICB0aGVtZShwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChoanVzdD0wLjUpKQpgYGAKCiAgIAogICAgIAojIyMjI2MpIEFyZSB5b3Ugc3VycHJpc2VkIGJ5IHRoZSByZXN1bHRzIG9yIGFyZSB0aGV5IHdoYXQgeW91IHdvdWxkIGhhdmUgZXhwZWN0ZWQ/ICAKCkkgYW0gbm90IHF1aXRlIHN1cnByaXNlZCBieSB0aGUgcmVzdWx0cy4gSSB3b3VsZCBleHBlY3QgVVMgdG8gaGF2ZSB0aGUgaGlnaGVzdCBmcmVxdWVuY3kgb24gYm90aCB0aGUgZmF0aGVyIGFuZCBzb24gb2NjdXBhdGlvbnMgY29tcGFyZWQgdG8gVUsgb3IgSmFwYW4uIEEgcmVhc29uIGZvciB0aGlzIGlzIHRoZSBwb3B1bGF0aW9uIGZhY3Rvci4gSSBhbHNvIGV4cGVjdGVkIGEgc2ltaWxhciBwYXR0ZXJuIGZvciBvY2N1cGF0aW9uIGRpc3RyaWJ1dGlvbiBpbiBVSyBhY3Jvc3MgYWxsIGpvYiBjYXRlZ29yaWVzIGJldHdlZW4gdGhlIGZhdGhlcnMgYW5kIHRoZSBzb25zLiBZb3VuZ2VyIGdlbmVyYXRpb25zIHRlbmQgdG8gaGF2ZSBiZXR0ZXIgbGl2ZXMgYW5kIG1vcmUgb3Bwb3J0dW5pdGllcyBzdGF0aXN0aWNhbGx5LCB3aGVyZSBtb3N0IHBhcmVudHMgd2FudCB0byBzZXQgb3V0IGJldHRlciBwYXRocyBmb3IgdGhlaXIgY2hpbGRyZW4uIEl0IGlzIGRlZmluaXRlbHkgbW9yZSBjb21tb24gdG8gZW5jb3VudGVyIGZhdGhlcnMgd2l0aCBtYW51YWwgb3IgZmFybWluZyBqb2IgYW5kIHNvbnMgd2l0aCBub25tYW51YWwgbGFib3JzLgogICAKICAgICAgCiAgIAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gIAogIAojIyMjIFByb2JsZW0gMjogV2hpc2t5CipTb3VyY2U6IENoYXB0ZXIgNCwgcC4gNzMgbm8uIDYqCmZyb20gU2ltbW9ucyBTdXJ2ZXkuIFRoZSBXaGlza3kgZmlsZSBjb250YWlucyBhIGRhdGEgZnJhbWUgd2l0aCAyLDIxOCBvYnNlcnZhdGlvbnMgb24gdGhlIGZvbGxvd2luZyAyMSB2YXJpYWJsZXMuIEFsbCB2YXJpYWJsZXMgYXJlIGNvZGVkIDEgaWYgY29uc3VtZWQgaW4gbGFzdCB5ZWFyLCAwIGlmIG5vdC4KICAgICAKIyMjIyNhKSBEcmF3IGEgYmFyY2hhcnQgb2YgdGhlIG51bWJlciBvZiByZXNwb25kZW50cyBwZXIgYnJhbmQuIFdoYXQgb3JkZXJpbmcgb2YgdGhlIGJyYW5kcyBkbyB5b3UgdGhpbmsgaXMgYmVzdD8gIAogICAKVGhlIGZvbGxvd2luZyBncmFwaCBzaG93cyB0aGUgZnJlcXVlbmN5IG9mIGJyYW5kcyB1c2VkIGluIGxhc3QgeWVhciBmb3IgdGhlIHJlc3BvbmRlbnRzIHdobyByZXBvcnQgY29uc3VtaW5nIHNjb3RjaC4gV2Ugc2VlIHRoYXQgc2NvdGNoIENoaXZhcyBSZWdhbCB3YXMgcmVwb3J0ZWQgdG8gYmUgdGhlIG1vc3QgY29uc3VtZWQsIGFuZCBTaW5nbGV0b24gd2FzIHRoZSBsZWFzdCBjb25zdW1lZC4KYGBge3J9CnJtKGxpc3Q9bHMoKSkKZGF0YShTY290Y2gpO2RmPC1TY290Y2g7IHJtKFNjb3RjaCkKc2RhdGE8LWFzLmRhdGEuZnJhbWUoY29sU3VtcyhkZikpO3NkYXRhJHRlbXA8LXJvd25hbWVzKHNkYXRhKTsgY29sbmFtZXMoc2RhdGEpPC1jKCJGcmVxdWVuY3kiLCJXaGlza2V5IikKCiMgUGxvdHRpbmcgdGhlIGdyYXBoOgpnZ3Bsb3Qoc2RhdGEsYWVzKHg9V2hpc2tleSx5ID0gRnJlcXVlbmN5KSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgZmlsbCA9ICJsaWdodGJsdWUiLCBjb2xvdXIgPSAiYmxhY2siKSArIAogIGNvb3JkX2ZsaXAoKSsgZ2d0aXRsZSgiTnVtYmVyIG9mIFJlc3BvbmRlbnRzIGJ5IFNjb3RjaCBCcmFuZHMiKSArIAogIHhsYWIoIlNjb3RjaCBCcmFuZHMiKSArCiAgdGhlbWUocGxvdC50aXRsZT1lbGVtZW50X3RleHQoaGp1c3Q9MC41KSkgKyBzY2FsZV9maWxsX2dyZXkoKQpgYGAKXApcCkluIG9yZGVyIHRvIHNlZSB0aGUgZGlzdHJpYnV0aW9uIG1vcmUgY2xlYXJseSwgaXQgd291bGQgYmUgYmVzdCB0byBzb3J0IHRoZSBicmFuZCBpbiB0aGUgZGVzY2VuZGluZyBvcmRlciBieSBpdHMgZnJlcXVlbmN5IG9mIHVzZS4gSW4gdGhpcyBjYXNlLCBDaGl2YXMgUmVnYWwgd291bGQgYmUgb24gdGhlIHRvcCBhbmQgdGhlIFNpbmdsZXRvbiB3b3VsZCBiZSBhdCB0aGUgdmVyeSBib3R0b20gb2YgdGhlIGdyYXBoLgoKYGBge3J9CiMgUGxvdHRpbmcgdGhlIGdyYXBoIGluIGRlc2NlbmRpbmcgb3JkZXI6CmdncGxvdChzZGF0YSxhZXMoeD1yZW9yZGVyKFdoaXNrZXksRnJlcXVlbmN5KSx5ID0gRnJlcXVlbmN5KSkgKwogIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IiwgZmlsbCA9ICJsaWdodGJsdWUiLCBjb2xvdXIgPSAiYmxhY2siKSArIAogIGNvb3JkX2ZsaXAoKSsgZ2d0aXRsZSgiTnVtYmVyIG9mIFJlc3BvbmRlbnRzIGJ5IFNjb3RjaCBCcmFuZHMiKSArIAogIHhsYWIoIlNjb3RjaCBCcmFuZHMiKSArCiAgdGhlbWUocGxvdC50aXRsZT1lbGVtZW50X3RleHQoaGp1c3Q9MC41KSkgKyBzY2FsZV9maWxsX2dyZXkoKQpgYGAKICAgCiAgICAKIyMjIyNiKSBUaGVyZSBhcmUgMjAgbmFtZWQgYnJhbmRzIGFuZCBhIGZ1cnRoZXIgY2F0ZWdvcnkgT3RoZXIuYnJhbmRzLiBQbG90IGEgY2hhcnQgY29udGFpbmluZyBiaWcgYnJhbmRzIGFuZCBncm91cGluZyBzbWFsbGVyIGJyYW5kIG5hbWVzIHRvICJPdGhlciIgYnJhbmQuIFdoYXQgY3V0b2ZmIHdvdWxkIHlvdSB1c2UgZm9yIGRlZmluaW5nIGEgYmlnIGJyYW5kPyAgCiAgIApBY2NvcmRpbmcgdG8gdGhlIG9yZGVyZWQgZ3JhcGggaW4gKGEpLCB3ZSBzZWUgdGhhdCB0aGUgZnJlcXVlbmN5IGRyb3BzIHNpZ25pZmljYW50bHkgYWZ0ZXIgR2xlbmZpZGRpY2ggYnJhbmQuIFRoYXQgaXMsIGZyb20gb3ZlciAzMDAgdG8gYSBsaXR0bGUgb3ZlciAxMDAuIFRoaXMgd291bGQgdGhlcmVmb3JlIGJlIGEgZ29vZCBjdXRvZmYgcG9pbnQgKGUuZy4gMzAwKSBmb3IgZ3JvdXBpbmcgdGhvc2Ugd2l0aCBmcmVxdWVuY3kgbGVzcyB0aGFuIHRoYXQgb2YgR2xlbmZpZGRpY2ggc2NvdGNoIHRvIGJyYW5kICJPdGhlciIuCmBgYHtyfQojIERlZmluaW5nIGEgYnJhbmQgbmFtZSBPdGhlcjoKc2RhdGFncm91cCA8LSBzZGF0YQpzZGF0YWdyb3VwJEZyZXF1ZW5jeVt3aGljaChzZGF0YWdyb3VwJFdoaXNrZXk9PSJPdGhlci5CcmFuZHMiKV0gPSBzZGF0YWdyb3VwJEZyZXF1ZW5jeVt3aGljaChzZGF0YWdyb3VwJFdoaXNrZXk9PSJPdGhlci5CcmFuZHMiKV0gKyAKICBzdW0oKHNkYXRhZ3JvdXAgJT4lIGZpbHRlcihGcmVxdWVuY3kgPCAzMDApKSRGcmVxdWVuY3kpCgojIFBsb3QgdGhlIGdyYXBoCmZvcnBsb3QgPC0gc2RhdGFncm91cCAlPiUgZmlsdGVyKEZyZXF1ZW5jeT4zMDApCmdncGxvdChmb3JwbG90LGFlcyh4PXJlb3JkZXIoV2hpc2tleSxGcmVxdWVuY3kpLHkgPSBGcmVxdWVuY3kpKSArCiAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBmaWxsID0gInBpbmsiLCBjb2xvdXIgPSAiYmxhY2siKSArIAogIGNvb3JkX2ZsaXAoKSsgZ2d0aXRsZSgiTnVtYmVyIG9mIFJlc3BvbmRlbnRzIGJ5IFNjb3RjaCBCcmFuZHMiKSArIAogIHhsYWIoIlNjb3RjaCBCcmFuZHMiKSArCiAgdGhlbWUocGxvdC50aXRsZT1lbGVtZW50X3RleHQoaGp1c3Q9MC41KSkgKyBzY2FsZV9maWxsX2dyZXkoKQpgYGAKCiMjIyMjYykgVHdvIG90aGVyIGRhdGFzZXQgdmVyc2lvbnMgYXJlIGNhbGxlZCB3aGlza2V5IGFuZCB3aGlza2V5X2JyYW5kcy4gSG93IGRvIHlvdSBpbmNvcnBvcmF0ZSB0aGlzIGluZm9ybWF0aW9uIGluIHlvdXIgZ3JhcGhpY3M/IEJ5IHVzaW5nIGEgZGlmZmVyZW50IG9yZGVyaW5nLCBhIGNvbG91ciwgb3IgZHJhd2luZyB0d28gZ3JhcGhpY3MgcmF0aGVyIHRoYW4gb25lPwogICAKICAgClRvIGluY29ycG9yYXRlIHRoaXMgYm90aCB3aGlza2V5IGFuZCB3aGlza2V5X2JyYW5kcyBpbiBvbmUgZ3JhcGhpYywgSSB3b3VsZCBhZGQgYm90aCBJbmNpZGVuY2UgYW5kIEZyZXEgYW5kIHRoZW4gcGxvdCBpdCB3aXRoIGRpZmZlcmVudCBjb2xvcmluZyBhbmQgc3RhY2sgdGhlbSBvbiB0b3Agb2YgZWFjaCBvdGhlci4gQWZ0ZXIgdHJ5aW5nIG91dCBkaWZmZXJlbnQgZ3JhcGhzLCBJIGNob3NlIHRvIGluY29ycG9yYXRlIGl0IHRoaXMgd2F5IGJlY2F1c2UgdGhlIGdyYXBoIGxvb2tzIGluZm9ybWF0aXZlIGFuZCBpbnZvbHZlcyBib3RoIG9yZGVyaW5nIGFuZCBjb2xvcnMuIEZvciBpbnN0YW5jZSwgaW4gdGhlIGZvbGxvd2luZyBncmFwaCB3ZSBjYW4gc2VlIGRpZmZlcmVudCB0eXBlcyAoQmxlbmQgdi4gU2luZ2xlIE1hbHQpIGFuZCBvcmlnaW5zIG9mIHZhcmlvdXMgd2hpc2tleSBicmFuZHMgKHBsYWNlcyBhcyBhIGxlZ2VuZCkuCmBgYHtyfQpsaWJyYXJ5KGZsZXhtaXgpCnJtKGxpc3Q9bHMoKSkKZGF0YSgid2hpc2tleSIpCndkYXRhIDwtIGFzLmRhdGEuZnJhbWUoY29sU3Vtcyh3aGlza2V5JEluY2lkZW5jZSt3aGlza2V5JEZyZXEpKQp3ZGF0YSR0ZW1wIDwtIHJvd25hbWVzKHdkYXRhKQpjb2xuYW1lcyh3ZGF0YSkgPC0gYygiRnJlcXVlbmN5IiwiQnJhbmQiKQpzdW0gPC0gbWVyZ2Uod2RhdGEsd2hpc2tleV9icmFuZHMsYnk9IkJyYW5kIikKCnN1bSA8LSBzdW0gJT4lIGFycmFuZ2UoZGVzYyhGcmVxdWVuY3kpKQp0IDwtIHN1bQp0JEZyZXF1ZW5jeVt3aGljaCh0JEJyYW5kPT0iT3RoZXIgYnJhbmRzIildPXQkRnJlcXVlbmN5W3doaWNoKHQkQnJhbmQ9PSJPdGhlciBicmFuZHMiKV0gKyBzdW0oKHQlPiVmaWx0ZXIoRnJlcXVlbmN5IDwgMzAwKSkkRnJlcXVlbmN5KQoKZm9ycGxvdDwtdCAlPiVmaWx0ZXIoRnJlcXVlbmN5ID4gMzAwKTsgcm0odCkKZ2dwbG90KHN1YnNldChzdW0sQnJhbmQhPSJPdGhlciBicmFuZHMiKSxhZXMoeD1Cb3R0bGVkLHk9RnJlcXVlbmN5LCBmaWxsPXJlb3JkZXIoQnJhbmQsRnJlcXVlbmN5KSkpICsgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiKStmYWNldF93cmFwKH5UeXBlKSsKICBnZ3RpdGxlKCJXaGlza2V5IEJyYW5kcyBieSBUeXBlIGFuZCBPcmlnaW4iKSt0aGVtZShwbG90LnRpdGxlPWVsZW1lbnRfdGV4dChoanVzdD0wLjUpKSsgc2NhbGVfZmlsbF9kaXNjcmV0ZShuYW1lPSJCcmFuZHMiKSArIHhsYWIoIk9yaWdpbiIpCmBgYAoKVGhlIGRhdGEgc2V0IGlzIGZyb20gU2ltbW9ucyBTdHVkeSBvZiBNZWRpYSBhbmQgTWFya2V0cyBhbmQgY29udGFpbnMgdGhlIGluY2lkZW5jZSBtYXRyaXggZm9yIHNjb3RjaCBicmFuZHMgdXNlZCBpbiBsYXN0IHllYXIgZm9yIHRob3NlIGhvdXNlaG9sZHMgd2hvIHJlcG9ydCBjb25zdW1pbmcgc2NvdGNoLiAgCiAgIAojIyMjI2QpIFdoaWNoIHNwZWxsaW5ncywgJ3doaXNreScgb3IgJ3doaXNrZXknIGlzIG1vcmUgYXBwcm9wcmlhdGU/ClRoZSBzcGVsbGluZyB3aGlza3kgaXMgZ2VuZXJhbGx5IHVzZWQgZm9yIHdoaXNraWVzIGRpc3RpbGxlZCBpbiBTY290bGFuZCwgQ2FuYWRhLCBBdXN0cmFsaWEsIEphcGFuIGFuZCBFdXJvcGUsIHdoaWxlIHdoaXNrZXkgaXMgdXNlZCBmb3IgdGhlIHNwaXJpdHMgZGlzdGlsbGVkIGluIElyZWxhbmQgYW5kIEFtZXJpY2EuIEluIHRoaXMgY2FzZSwgc2luY2UgbWFueSBvZiB0aGVzZSBicmFuZHMgY29tZSBmcm9tIFNjb3RsYW5kLCBpdCB3b3VsZCBiZSBtb3JlIGFwcHJvcHJpYXRlIHRvIHVzZSB3aGlza3kgdGhhbiB3aGlza2V5LgogICAKICAgICAgCiAgIAotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KIyMjIyBQcm9ibGVtIDM6IE9saXZlIE9pbHMgZnJvbSBJdGFseQoqU291cmNlOiBDaGFwdGVyIDUsIHAuIDk3IG5vLiA4KgpWYXJpb3VzIGZhdHR5IGFjaWQgbWVhc3VyZW1lbnRzLiBBIGRhdGEgZnJhbWUgd2l0aCA1NzIgb2JzZXJ2YXRpb25zLgoKCiMjIyMjYSkgRHJhdyBhIGRlZmF1bHQgcGFyYWxsZWwgY29vcmRpbmF0ZSBwbG90IGFuZCBkZXNjcmliZSB2YXJpb3VzIGZlYXR1cmVzIHlvdSBjYW4gc2VlLgpGcm9tIHRoZSBncmFwaCBiZWxvdywgeW91IGNhbiBzZWUgdGhhdCB0aGVyZSBhcmUgMTEgdmFyaWFibGVzIG9mIHRoZSBvbGl2ZSBkYXRhc2V0LCBjb250YWluaW5nIGVpY29zZW5vaWMsIGFyYWNoaWRpYywgbGlub2xlbmljLCBsaW5vbGVpYywgYW5kIHNvIG9uLiBUaGVzZSBmZWF0dXJlcyBjb3JyZWxhdGUgdG8gZWFjaCBvdGhlciBpbiB3aXRoaW4gdGhlaXIgcmVnaW9uOiBub3RoLCBzb3V0aCBvciBzYXJkaW5pYS4KLi4KYGBge3J9CmxpYnJhcnkoZXh0cmFjYXQpCgojIE9wZW4gYW5kIHJlYWQgdGhlIGRhdGEKZGF0YSgib2xpdmVzIikKcm0obGlzdD1scygpKQpkPC1vbGl2ZXMKY29scyA8LSBjKCJyZWQiLCAiYmx1ZSIsICJvcmFuZ2UiKQpwbG90KGRbLDM6MTBdLCAKICAgICBjb2wgPSBjb2xzW29saXZlcyRSZWdpb25dLCAKICAgICBwY2ggPSAxNiwKbWFpbj0iT2xpdmVzIFByb3RlaW4gQWNpZCBNYXRyaXggU2NhdHRlcnBsb3QgXG4gTGVnZW5kOiBSZWQtTm9ydGgsIE9yYW5nZS1Tb3V0aCwgQmx1ZS1TCmFyZGluaWFdIikKYGBgCgpgYGB7cn0KZ2dwYXJjb29yZChkLCBzY2FsZSA9ICJ1bmltaW5tYXgiLApncm91cENvbHVtbiA9ICJSZWdpb24iKStnZW9tX2xpbmUoYWxwaGE9LjI1KSsKZ2d0aXRsZSgiUENQIGZvciBPbGl2ZSBEYXRhc2V0IikrCnRoZW1lKHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGhqdXN0PTAuNSksCnBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJsaWdodGdyYXkiKSkgKyBjb29yZF9mbGlwKCkKYGBgCgoKIyMjIyNiKSBEcmF3IHRoZSBzYW1lIHBsb3QgYW5kIGNvbG9yIHRoZSBvaWxzIGJ5IHRoZSByZWdpb24gdGhleSBjb21lIGZyb20uIFdoYXQgYWRkaXRpb25hbCBpbmZvcm1hdGlvbiBjYW4geW91IGZpbmQ/ClBhbG1pdGljIGFuZCBwYWxtaXRvbGVpYyBhcmUgcG9zaXRpdmVseSBjb3JyZWxhdGVkIHRvIGVhY2ggb3RoZXIuIE9sZWljIGlzIG5lZ2F0aXZlbHkgY29ycmVsYXRlZCB3aXRoIHBhbG1pdGljLCBwYWxtaXRvbGVpYyBhbmQgbGlub2xlaWMuCgojIyMjI2MpIERpc2N1c3Mgd2hpY2ggZmVhdHVyZXMgb2YgdGhlIGRhdGFzZXQgYXJlIGVhc2llciB0byBzZWUgd2l0aCBhIFBDUCBwbG90IGFuZCB3aGljaCBhcmUgZWFzaWVyIHRvIHNlZSB3aXRoIGEgc2NhdHRlcnBsb3QgbWF0cml4PwpJdCBpcyBlYXNpZXIgdG8gc2VlIGluIHNjYXR0ZXJwbG90IG1hdHJpeCB0aGFuIFBDUCwgYXMgd2UgY2FuIHNlZSBvdXRsaWVycyBhbmQgc2lnbmlmaWNhbmNlIG9mIGVhY2ggdmFyaWFibGUgbW9yZSBjbGVhcmx5LiBDbHVzdGVyIGdyb3VwcyBhbmQgdGhlIGRpYWdvbmFsIG1hdHJpY2VzIGhlbHAgaWRlbnRpZnkgYmV0dGVyIHRoZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIG9uZSB2YXJpYWJsZSB0byBhbm90aGVyLiBJdCBpcyBhIGxpdHRsZSBoYXJkZXIgdG8gc2VlIHVzaW5nIFBDUCBzaW5jZSB0aGUgb3JkZXJpbmcgYmVjb21lcyBtb3JlIHNlbnNpYmxlLiBIb3dldmVyLCB3ZSBzZWUgdGhhdCB0aGVyZSBtYXkgYmUgc29tZSBzdWJncm91cCBvZiBjbGFzc2VzIHdpdGhpbiBQQ1AgdGhhdCB3b3VsZCBiZSBhbiBhZHZhbnRhZ2Ugb3ZlciBzY2F0dGVycGxvdC4KICAgCiAgICAgIAogICAKLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiMjIyMgUHJvYmxlbSA0OiBIZXJ0enNwcnVuZy1SdXNzZWxsCipTb3VyY2U6IENoYXB0ZXIgNSwgcC4gOTcgbm8uIDEwKgpEYXRhIGZvciB0aGUgSGVydHpzcHJ1bmctUnVzc2VsbCBEaWFncmFtIG9mIHRoZSBTdGFyIENsdXN0ZXIgQ1lHIE9CMSwgd2hpY2ggY29udGFpbnMgNDcgc3RhcnMKaW4gdGhlIGRpcmVjdGlvbiBvZiBDeWdudXMsIGZyb20gQy5Eb29tLiBUaGUgZmlyc3QgdmFyaWFibGUgaXMgdGhlIGxvZ2FyaXRobSBvZiB0aGUgZWZmZWN0aXZlIHRlbXBlcmF0dXJlIGF0IHRoZSBzdXJmYWNlIG9mIHRoZSBzdGFyIChUZSkgYW5kIHRoZSBzZWNvbmQgb25lIGlzIHRoZSBsb2dhcml0aG0gb2YgaXRzIGxpZ2h0IGludGVuY2l0eQooTC9MMCkuClwKQSBkYXRhIGZyYW1lIHdpdGggNDcgb2JzZXJ2YXRpb25zIG9uIHRoZSBmb2xsb3dpbmcgMiB2YXJpYWJsZXMKbG9nLlRlIExvZ2FyaXRobSBvZiB0aGUgZWZmZWN0aXZlIHRlbXBlcmF0dXJlIGF0IHRoZSBzdXJmYWNlIG9mIHRoZSBzdGFyIChUZSkuCmxvZy5saWdodCBMb2dhcml0aG0gb2YgaXRzIGxpZ2h0IGludGVuY2l0eSAoTC9MMCkuCgojIyMjI2EpIFBsb3QgWSBhZ2FpbnN0IFguIEhvdyBkb2VzIHRoZSBwbG90IGRpZmZlciBmcm9tIHRoZSBwbG90cyB5b3UgZmluZCBvbiB0aGUgd2ViLCBmb3IgaW5zdGFuY2UgZnJvbSBhIGdvb2dsZSBzZWFyY2ggZm9yIGltYWdlcyBvZiB0aGlzIGRpYWdyYW0/ClRoZSBwbG90IGJlbG93IHNob3dzIHRoYXQgSGVydHpzcHJ1bmctUnVzc2VsbCBkaWFncmFtcyBwbG90IHN0YXIgbHVtaW5vc2l0eSAoYnJpZ2h0bmVzcykgYWdhaW5zdCB0ZW1wZXJhdHVyZSAoY29sb3VyKS4gVGhlIGZpcnN0IG9uZSB3YXMgZHJhd24ganVzdCBvdmVyIDEwMCB5ZWFycyBhZ28sIGJhc2VkIG9uIGRhdGFzZXQgZnJvbSB0aGUgWWFsZSBUcmlnb25vbWV0cmljIFBhcmFsbGF4LgpgYGB7cn0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoJ2h0dHBzOi8vd3d3Lnd3dS5lZHUvZGVwdHMvc2t5d2lzZS9pbWcvaHJkaWFncmFtXzAxLmpwZycpCmBgYApgYGB7cn0KIyBJbnN0YWxsIGEgcGFja2FnZQpybShsaXN0PWxzKCkpCmxpYnJhcnkocm9idXN0YmFzZSkKbGlicmFyeShHREFkYXRhKQojIE9wZW4gYW5kIHJlYWQgdGhlIGRhdGEKZGF0YSgiSFJzdGFycyIpCmRhdGEoInN0YXJzQ1lHIikKcm0obGlzdD1scygpKQpzdGFyPC1IUnN0YXJzCnN0YXJzczwtc3RhcnNDWUcKCiMgUGxvdDoKcGxvdChzdGFyc3MsbWFpbj0iU3RhcnNDWUcgU2NhdHRlcnBsb3QiKQpgYGAKCmBgYHtyfQpnZ3Bsb3Qoc3RhcixhZXMoeD1CVix5PVYpKStnZW9tX3BvaW50KCkrZ2d0aXRsZSgiSFJzdGFyIFNjYXR0ZXJwbG90IikrCnRoZW1lKHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGhqdXN0PTAuNSksCnBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoKSkrIHNjYWxlX3lfcmV2ZXJzZSgpCmBgYApcClwKSFIgU2NhdHRlcnBsb3QgcmVzZW1ibGVzIHRoZSBncmFwaGljIGZvdW5kIG9uIGdvb2dsZSBiZXR0ZXIgY29tcGFyZWQgdG8gdGhhdCBvZiBTdGFyc0NZRy4gVGhpcyBtYWtlcyBzZW5zZSBiZWNhdXNlIHRoZXJlIGFyZSBtb3JlIGRhdGFwb2ludHMgc2hvd24gaW4gdGhlIGRpYWdyYW0uIEluIHRoZSBIZXJ0enNwcnVuZy1SdXNzZWxsIGRpYWdyYW0sIHdoaWNoIGlzIHRoZSBzY2F0dGVycGxvdCBvZiB0aGVzZSBkYXRhIHBvaW50cywgd2hlcmUgdGhlIGxvZyB0ZW1wZXJhdHVyZSBpcyBwbG90dGVkIGZyb20gbGVmdCB0byByaWdodCwgdHdvIGdyb3VwcyBvZiBwb2ludHMgYXJlIHNlZW46CnRoZSBtYWpvcml0eSB3aGljaCB0ZW5kIHRvIGZvbGxvdyBhIHN0ZWVwIGJhbmQgYW5kIGZvdXIgc3RhcnMgaW4gdGhlIHVwcGVyIGNvcm5lci4gSW4gdGhlIGFzdHJvbm9teQp0aGUgNDMgc3RhcnMgYXJlIHNhaWQgdG8gbGllIG9uIHRoZSBtYWluIHNlcXVlbmNlIGFuZCB0aGUgZm91ciByZW1haW5pbmcgc3RhcnMgYXJlIGNhbGxlZCDigJxnaWFudHPigJ0gKHRoZSBwb2ludHMgMTEsIDIwLCAzMCwgMzQpLgoKIyMjIyNiKSBUaGUgcGxvdHMgc2VlbSB0byB1c2UgZGlmZmVyZW50IG51bWJlcnMgb2Ygc3RhcnMuIEFyZSBzb21lIG1vcmUgbGlrZWx5IHRvIGJlIHVzZWQgdGhhbiBvdGhlcnM/Clllcy4gVGhlcmUgYXJlIHBsb3RzIHdpdGggbGVzcyBwb2ludHMgc2hvd2luZyB0aGUgY29tcG9zaXRpb24gYnV0IHRoZXJlIGFyZSBhbHNvIG90aGVyIHBsb3RzIHdpdGggbW9yZSBwb2ludHMgdGhhdCBzaG93IGV4YWN0IHNpdHVhdGlvbnMuIAoKIyMjIyNjKSBBbnkgc3VnZ2VzdGlvbnM/CkFmdGVyIHJlYWRpbmcgYSBmZXcgbm90ZXMgZnJvbSBDaGFwdGVyIDEzLCBJIHdvdWxkIHdhbnQgdG8gYmFzZSBteSBjb2xvcmluZyBvbiB0aGUgQlYgaW5kZXguIFRoaXMgd2F5LCB0aGUgZGlhZ3JhbSB3b3VsZCBoYXZlIG1vcmUgY29udHJhc3QsIGh1ZXMgYW5kIHNhdHVyYXRpb24uIEkgd291bGQgYWxzbyBtYW5pcHVsYXRlIGRhdGFwb2ludHMgb24gdGhlIGdyYXBoIGZvciBjbHVzdGVyaW5nIHB1cnBvc2VzLCB3aGljaCB3b3VsZCB0cmlnZ2VyIGlkZW50aWZ5aW5nIHBhdHRlcm5zIGFuZCBjb25jbHVzaW9uIGZyb20gdGhlIGRhdGEgKGFuIGV4YW1wbGUgaXMgdGhlIFN1cGVyIEdpYW50cyBjbHVzdGVyIG5hbWUpLgoKCiAgIAogICAgICAKICAgCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgCiAgIAojIyMjIFByb2JsZW0gNTogQm9keWZhdAoqU291cmNlOiBDaGFwdGVyIDYsIHAuIDEzMCBuby4gNSoKRGF0YXNldCBib2R5ZmF0IHByb3ZpZGVzIGVzdGltYXRlcyBvZiB0aGUgcGVyY2VudGFnZSBvZiBib2R5IGZhdCBvZiAyNTIgbWVuLCBkZXRlcm1pbmVkIGJ5IHVuZGVyd2F0ZXIgd2VpZ2hpbmcgYW5kIGJvZHkgY2lyY3VtZmVyZW5jZSBtZWFzdXJlbWVudHMuIERyYXcgYSBwYXJhbGxlbCBjb29yZGluYXRlIHBsb3QgZm9yIHRoZSBkYXRhc2V0LgoKYGBge3J9CiMgT3BlbiBhbmQgcmVhZCB0aGUgZGF0YQpsaWJyYXJ5KGRwbHlyKQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShzY2FsZXMpCmxvYWQoImJvZHlmYXQucmRhIikKCiNib2R5ZmF0CgojIERhdGEgY2xlYW5pbmcgYW5kIHdyYW5nbGluZzoKYm9keWZhdCRhZ2VncnAgPC0gYXMuZmFjdG9yKGN1dChib2R5ZmF0JGFnZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVha3M9YygyMSwzOSw2MCw4MSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWxzPWMoIjw0MCIsIjQwLTYwIiwiNjArIikpKQptbSA8LSBib2R5ZmF0ICU+JSByb3duYW1lc190b19jb2x1bW4oIklEIikgJT4lIGdhdGhlcihrZXksdmFsdWUsLUlELC1hZ2UsLWFnZWdycCkKbW0gPC0gbW0gJT4lIGdyb3VwX2J5KGtleSkgJT4lIG11dGF0ZSh2YWx1ZSA9IHJlc2NhbGUodmFsdWUpKQoKIyBQbG90dGluZzoKZ2dwbG90KG1tLCBhZXMoa2V5LCB2YWx1ZSwgZ3JvdXAgPSBJRCwgY29sb3IgPSBhZ2VncnApKSsKICBnZW9tX2xpbmUoYWxwaGE9MC4zNSkgKwogIGdndGl0bGUoIkJvZHlmYXQgUGFyYWxsZWwgQ29vcmRpbmF0ZSBQbG90IikgKwogIHRoZW1lKHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGhqdXN0PTAuNSksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImxpZ2h0Z3JheSIpKSArIHhsYWIoImJvZHkgcGFydCIpICsgeWxhYigidmFsdWUiKQpgYGAKCiMjIyMjYSkgQXJlIHRoZXJlIGFueSBvdXRsaWVycz8gV2hhdCBjYW4geW91IHNheSBhYm91dCB0aGVtPwpZZXMsIHRoZXJlIGFyZSBjZXJ0YWlubHkgb3V0bGllcnMuIFdlIGNhbiBzZWUgZnJvbSB0aGUgcGxvdCB0aGF0IHNvbWUgbGluZXMgZG8gbm90IGZvbGxvdyB0aGUgbm9ybWFsIGFnZ3JlZ2F0ZWQgbGluZXMgaW4gdGhlIG1pZGRsZS4gRm9yIGluc3RhY2UsIHNvbWUgaGF2ZSBwb2ludHMgaW4gMS4wMCB2YWx1ZSB3aGVuIG1ham9yaXR5IG9mIGxpbmVzIGFyZSBjbG9zZSB0byAwLjI1IGZvciBhbmtsZSBjYXRlZ29yeS4gV2UgY2FuIGFsc28gc2VlIGZyb20gdGhlIGZvbGxvd2luZyBQQ1AgcGxvdCB0aGF0IGlzIG9yZGVyZWQsIHNvbWUgbGluZXMgYXJlIG9mZiB0aGUgZmxvdywgZm9yIGluc3RhbmNlIHRoZSBncmVlbiBsaW5lcyBpbiB0aGUgdXBwZXIgcGFydCwgd2hpY2ggYWxzbyBjb25maXJtIG91ciBjbGFpbSBhYm91dCBleGlzdGluZyBvdXRsaWVycy4KCmBgYHtyfQojIFBsb3Qgb3JkZXJlZDoKbGlicmFyeShHR2FsbHkpCmdncGFyY29vcmQoYm9keWZhdCwgCiAgICAgICAgICAgY29sdW1ucyA9IGMoMToyLDQ6MTUpLCAKICAgICAgICAgICBzY2FsZSA9ICJ1bmltaW5tYXgiLAogICAgICAgICAgIGdyb3VwQ29sdW1uID0gImFnZWdycCIpKwogIGdlb21fbGluZShhbHBoYT0wLjM1KSArCiAgZ2d0aXRsZSgiT3JkZXJlZCBQQ1AgUGxvdCBmb3IgQm9keWZhdCBEYXRhc2V0IikrCiAgdGhlbWUocGxvdC50aXRsZT1lbGVtZW50X3RleHQoaGp1c3Q9MC41KSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAibGlnaHRncmF5IikpKyB4bGFiKCJib2R5IHBhcnQiKSArIHlsYWIoInZhbHVlIikKYGBgCgoKIyMjIyNiKSBDYW4geW91IGRlZHVjZSBhbnl0aGluZyBhYm91dCB0aGUgaGVpZ2h0IHZhcmlhYmxlPwpTcGVjaWZpY2FsbHkgZm9yIHRoZSBoZWlnaHQgdmFyaWFibGUsIHRoZSByYW5nZSBpcyB3aWRlLCBtZWFuaW5nIHRoYXQgZGF0YSByYW5nZXMgZnJvbSB0aGUgbG93ZXN0IHRvIHRoZSBoaWdoZXN0IHZhbHVlIChmcm9tIDAgdG8gMSkuIEl0IGFsc28gc3VnZ2VzdHMgdGhhdCB0aG9zZSB3aG8gYXJlIG9sZGVyIHdpdGggaGlnaGVyIGJvZHlmYXQgdGVuZCB0byBiZSBzaG9ydGVyIGFuZCB0aG9zZSB3aG8gYXJlIHlvdW5nZXIgd2l0aCBsb3cgYm9keWZhdCB0ZW5kIHRvIGJlIHRhbGxlci4gV2UgY2FuIGFsc28gZGVyaXZlIGZyb20gdGhpcyBjb25jbHVzaW9uIGFuZCB0aHJvdWdoIHRoZSBwbG90IHRoYXQgdGhlIGhlaWdodCB2YXJpYWJsZSBpcyBkaXJlY3RseSByZWxhdGVkIHRvIGFnZS4gCgojIyMjI2MpIFdoYXQgY2FuIHlvdSBzYXkgYWJvdXQgdGhlIHJlbGF0aW9uc2hpcCBiZXR3ZWVuIHRoZSBmaXJzdCB0d28gdmFyaWFibGVzOiBkZW5zaXR5IGFuZCBib2R5ZmF0PwpMb29raW5nIGF0IHRoZSBmb2xsb3dpbmcgZ3JhcGgsIHRoZSBkZW5zaXR5IHZhcmlhYmxlIGlzIGludmVyc2VseSBwcm9wb3J0aW9uYWwgdG8gdGhlIGJvZHlmYXQgdmFyaWFibGUsIHdpdGhpbiB0aGUgcmFuZ2Ugb2YgMC4wIGFuZCAxLjAuIEluIHRoaXMgY2FzZSwgd2hlbiBkZW5zaXR5IGlzIDEuMCwgYm9keWZhdCB3b3VsZCBiZSAwLjAuIFRvIG1ha2Ugc2Vuc2Ugb2YgdGhpcyB3ZSBjYW4gdGhpbmsgb2YgYm9uZXMgdGhhdCBhcmUgdmVyeSBoZWF2eSwgd2hpY2ggd291bGQgbm90IGhhdmUgYW55IGZhdC4KCmBgYHtyfQojIFBsb3QgY29kZXM6CmdncGFyY29vcmQoYm9keWZhdCwgY29sdW1ucyA9IGMoMToyLDQ6NSksIAogICAgICAgICAgIHNjYWxlID0gInVuaW1pbm1heCIsCiAgICAgICAgICAgZ3JvdXBDb2x1bW4gPSAiYWdlZ3JwIikgKwogIGdlb21fbGluZShhbHBoYT0uMzUpKwogIGdndGl0bGUoIkJvZHlmYXQgUENQIFBsb3QgdXNpbmcgRGVuc2l0eSwgQm9keWZhdCwgV2VpZ2h0LCBhbmQgSGVpZ2h0IikrCiAgdGhlbWUocGxvdC50aXRsZT1lbGVtZW50X3RleHQoaGp1c3Q9MC41KSwKICAgICAgICBwYW5lbC5iYWNrZ3JvdW5kID0gZWxlbWVudF9yZWN0KGZpbGwgPSAibGlnaHRncmF5IikpKyB4bGFiKCJib2R5IHBhcnQiKSArIHlsYWIoInZhbHVlIikKYGBgCgojIyMjI2QpIERvIHlvdSB0aGluayB0aGUgb3JkZXJpbmcgb2YgdGhlIHZhcmlhYmxlcyBpcyBzZW5zaWJpbGU/IFdoYXQgYWx0ZXJuYXRpdmUgb3JkZXJpbmdzIG1pZ2h0IGJlIGluZm9ybWF0aXZlPwpZZXMsIHRoZSBvcmRlcmluZyBvZiB2YXJpYWJsZXMgaXMgc2Vuc2libGUuIFdlIGNhbiBzZWUgZnJvbSB0aGUgYWJvdmUgcGxvdCB0aGF0IHdoZW4gcGFpcmVkIG9yIGNvbXBhcmVkIHNpZGUgYnkgc2lkZSwgdHdvIHZhcmlhYmxlcyBpbiBQQ1AgcGxvdHMgY2FuIHNob3cgc3Ryb25nIGNvcnJlbGF0aW9uLCBmb3IgaW5zdGFuY2UgaW4gdGhlIGNhc2UgZm9yIGRlbnNpdHkgYW5kIGJvZHlmYXQuIEFuIGFsdGVybmF0aXZlIG9yZGVyaW5ncyB0aGF0IG1pZ2h0IGJlIGluZm9ybWF0aXZlIGlzIHNwbGl0dGluZyBpdCBpbnRvIGFnZSBncm91cHMsIGFzIHNob3duIGJlbG93LiBCeSBmbGlwcGluZyB0aGUgYXhpcyBhbmQgb2JzZXJ2aW5nIHRocm91Z2ggZGlmZmVyZW50IGFnZSBncm91cHMsIHdlIGNhbiBhbHNvIHNlZSBob3cgYm9keXBhcnRzIGNvcnJlbGF0ZSB0byBvbmUgYW5vdGhlciBpbiB0aGVpciBvcmRlci4gQWxsIGFnZSBncm91cHMgc2VlbSB0byBzaGFyZSBzaW1pbGFyIHBhdHRlcm4uCgpgYGB7cn0KZ2dwYXJjb29yZChib2R5ZmF0LCBjb2x1bW5zID0gYygxOjIsNDoxNSksIAogICAgICAgICAgIHNjYWxlID0gInVuaW1pbm1heCIsCiAgICAgICAgICAgZ3JvdXBDb2x1bW4gPSAiYWdlZ3JwIikrCiAgZ2VvbV9saW5lKGFscGhhPTAuMjApKwogIGZhY2V0X3dyYXAofmFnZWdycCkgKyAKICBnZ3RpdGxlKCJCb2R5ZmF0IERhdGFzZXQgUENQIGJ5IEFnZSBHcm91cCIpKwogIHRoZW1lKHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGhqdXN0PTAuNSksCiAgICAgIHBhbmVsLmJhY2tncm91bmQgPSBlbGVtZW50X3JlY3QoZmlsbCA9ICJsaWdodGdyYXkiKSkreGxhYigiYm9keSBwYXJ0IikgKyB5bGFiKCJ2YWx1ZSIpKwogIGNvb3JkX2ZsaXAoKQpgYGAKCiAgIAogICAgICAKICAgCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgCiAgIAojIyMjIFByb2JsZW0gNjogV2luZQoqU291cmNlOiBDaGFwdGVyIDYsIHAuIDEzMCBuby4gNyoKVGhlIHdpbmUgZGF0YXNldCBjb250YWlucyBkYXRhIG9mIHRocmVlIGNsYXNzZXMgb2Ygd2luZS4KIyMjIyNhKSBVc2UgUENQIHRvIGludmVzdGlnYXRlIGhvdyB3ZWxsIHRoZSB2YXJpYWJsZXMgc2VwYXJhdGUgdGhlc2UgY2xhc3Nlcy4KVmFyaWFibGUgZGF0YSBhY3Jvc3MgY2xhc3NlcyBhcmUgcHJldHR5IGNvbnNpc3RlbnQuIEJsdWUgbGluZXMgKGNsYXNzKQpgYGB7ciwgbWVzc2FnZT1GQUxTRX0KbGlicmFyeShwZ21tKQpsaWJyYXJ5KGdjbHVzKQpsaWJyYXJ5KHJhdHRsZSkKCnJtKGxpc3Q9bHMoKSkKZGF0YSh3aW5lKQojIHdpbmUgPC0gYXMuZGF0YS5mcmFtZSh3aW5lKQpnZ3BhcmNvb3JkKHdpbmUsIGNvbHVtbnMgPSBjKDE6MTMpLCBzY2FsZSA9ICJ1bmltaW5tYXgiLAogICAgICAgICAgIGdyb3VwQ29sdW1uID0gImNsYXNzIikrCiAgZ2VvbV9saW5lKGFscGhhPTAuMjEpKwogIGZhY2V0X3dyYXAofmNsYXNzLCBuY29sID0gMSkrCiAgZ2d0aXRsZSgiV2luZSBDaGFyYWN0ZXJpc3RpYyBieSBDbGFzcyIpKwogIHRoZW1lKHBsb3QudGl0bGU9ZWxlbWVudF90ZXh0KGhqdXN0PTAuNSksCiAgICAgICAgcGFuZWwuYmFja2dyb3VuZCA9IGVsZW1lbnRfcmVjdChmaWxsID0gImxpZ2h0Z3JheSIpKSsKICB4bGFiKCJXaW5lIENoYXJhY3RlcmlzdGljIikgKyAKICB5bGFiKCJWYWx1ZSIpKwogIGNvb3JkX2ZsaXAoKQpgYGAKCmBgYHtyLCBlY2hvPUZBTFNFfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygnL1VzZXJzL01vb3Jpc3NhL0Rlc2t0b3Avd2luZWNsYXNzLnBuZycpCmBgYAoKIyMjIyNiKSBBcmUgdGhlcmUgYW55IG91dGxpZXJzPwpZZXMsIGJ5IG9ic2VydmluZyB0aGUgZ3JhcGggYWJvdmUgd2Ugc2VlIHRoYXQgdGhlcmUgYXJlIHNvbWUgb3V0bGllcnMgd2l0aGluIGVhY2ggY2xhc3MsIEJhcmJlcmEsIEJhcm9sbyBhbmQgR3JpZ25vbGluby4gSG93ZXZlciwgZGF0YSBsb29rIHZlcnkgY29uc2lzdGVudCBhbmQgaGVuY2Ugb3V0bGllcnMgd291bGQgbm90IGFmZmVjdCB0aGUgZGF0YXNldCBhcyBtdWNoLiBXZSBzZWUgdGhhdCBkYXRhIHBvaW50cyBpbiBHcmlnbm9saW5vIGhhcyBtb3JlIG91dGxpZXJzIHRoYW4gQmFyYmVyYSBvciBCYXJvbG8uIAoKIyMjIyNjKSBJcyB0aGVyZSBldmlkZW5jZSBvZiBzdWJncm91cHMgd2l0aGluIHRoZSBjbGFzc2VzPwpXZSBjYW4gcGVyaGFwcyBzYXkgdGhhdCB0aGVyZSBhcmUgc3ViZ3JvdXBzIHdpdGhpbiB0aGVzZSBjbGFzc2VzLiBGb3IgaW5zdGFuY2UsIHRoZSB2ZXJ5IHRpZ2h0IGxpbmVzIGFtb25nIGRpZmZlcmVudCBjbGFzc2VzIHN1Z2dlc3QgdGhlaXIgc2FtZSBleGFjdCBwYXR0ZXJucyBhbmQgYmVoYXZpb3JzLiBIb3dldmVyLCB0aGVyZSBhcmUgc29tZSBsaW5lcyB0aGF0IGRvIG5vdCBmb2xsb3cgY2VydGFpbiBmbG93IGFzIHRoZSBvdGhlciAoZS5nLiBzbG9wZXMgYXJlIG5lZ2F0aXZlIHdoZW4gYSBzdWJjbGFzcyBzaG93cyBhbiBpbmNyZWFzaW5nIGxpbmUgb3IgcG9zaXRpdmUgc2xvcGUpLCBidXQgdGhleSBhcmUgbm90IG91dGxpZXJzIGFzIHdlbGwgYmVjYXVzZSB0aGVyZSBhcmUgbWFueSBvZiB0aGVtIHRoYXQgYmVoYXZlIHZlcnkgc2ltaWxhcmx5LiBJbiB0aGlzIGNhc2UsIHdlIGNhbiBjYWxsIHRoZXJlIGFyZSBhIGZldyBzdWJncm91cHMgd2l0aGluIHRoZSBjbGFzc2VzLgoKCiAgIAogICAgICAKICAgCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAgCiAgIAojIyMgUEFSVCBJSQoqKkNob29zZSB0d28gZGF0YXNldHMgZnJvbSB0aGUgYWJvdmUgZXhlcmNpc2VzLiBGb3IgZWFjaCwgcHJvdmlkZSBpbnNpZ2h0LCB0aHJvdWdoIGdyYXBocyBhbmQgdGV4dCwgb24gYW4gaXNzdWUgdGhhdCBnb2VzIGJleW9uZCB0aG9zZSBkaXNjdXNzZWQgaW4gdGhlIGhvbWV3b3JrIGV4ZXJjaXNlcy4gQW55IHR5cGUgb2YgZ3JhcGggaXMgcGVybWl0dGVkLCB3aGV0aGVyIG9yIG5vdCBjb3ZlcmVkIGluIGNsYXNzLCBzbyB5b3UgbWF5IHRha2UgdGhpcyBhcyBhbiBvcHBvcnR1bml0eSB0byBleHBsb3JlIG5ldyBvcHRpb25zLiAqKiAgCiAgICAKYGBge3J9CiMgVGhpcmQgZGF0YXNldDoKbGlicmFyeShleHRyYWNhdCkKCiMgT3BlbiBhbmQgcmVhZCB0aGUgZGF0YQpkYXRhKCJvbGl2ZXMiKQpybShsaXN0PWxzKCkpCmQ8LW9saXZlcwpjb2xzIDwtIGMoIm9yYW5nZSIsICJyZWQiLCAiZ3JlZW4iKQoKZ2dwbG90KGQsYWVzKHg9YXJhY2hpZGljLHk9c3RlYXJpYywgY29sb3VyPSBSZWdpb24sIHNpemU9MykpK2dlb21fcG9pbnQoKSsKICBmYWNldF93cmFwKH5BcmVhKSsgZ2d0aXRsZSgiU2NhdHRlcnBsb3QgYnkgQXJlYXMiKSsgdGhlbWUocGxvdC50aXRsZT1lbGVtZW50X3RleHQoaGp1c3Q9MC41KSkKYGBgCgoKCmBgYHtyfQojIEZpcnN0IGRhdGFzZXQKZGF0YShZYW1hZ3VjaGk4NykKeSA8PC0gZGF0YS5mcmFtZShZYW1hZ3VjaGk4NykKIyBPdmVyYWxsIGRpc3RyaWJ1dGlvbiBwbG90CmdncGxvdCh5LGFlcyhDb3VudHJ5LEZyZXEsZmlsbD1Tb24pKSArIGdlb21fYmFyKHN0YXQ9ImlkZW50aXR5IikgKyAKICBnZ3RpdGxlKCJPdmVyYWxsIE9jY3VwYXRpb24gRGlzdHJpYnV0aW9ucyBvZiB0aGUgU29ucyBpbiBVUywgVUssIGFuZCBKYXBhbiIpCmBgYApcCkkgYWx3YXlzIGxpa2Ugc3RhY2tlZCBiYXIgY2hhcnRzIHNpbmNlIGl0IHNob3dzIGFuIG92ZXJhbGwgc3VtIG9mIGZyZXF1ZW5jaWVzIG9mIGRpZmZlcmVudCBncm91cHMuIFRha2luZyB0aGUgZmlyc3QgcHJvYmxlbSBpbiBhbm90aGVyIGFwcHJvYWNoLCBJJ2QgbGlrZSB0byBzZWUgdGhlIG92ZXJhbGwgcGxvdCBvZiB0aGUgZGlzdHJpYnV0aW9uIG9mIG9jY3VwYXRpb25zIG9mIHRoZSBzb25zIGFib3ZlLCB0aGUgbnVtYmVyIG9mIGpvYnMgYXJlIGhpZ2hlc3QgaW4gVVMgY29tcGFyZWQgdG8gVUsgb3IgSmFwYW4gaW4gYWxsIG9jY3VwYXRpb24gYXJlYXMsIGluY2x1ZGluZyB0aG9zZSBjYXRlZ29yaXplZCBhcyBVcHBlciBOb25NYW51YWxzIChVcE5NKSwgTG93ZXIgTm9uTWFudWFscyAoTG9OTSksIFVwcGVyIE1hbnVhbHMgKFVwTSksIExvd2VyIE1hbnVhbHMgKExvTk0pLCBhbmQgRmFybWluZyAoRmFybSkuIFRoaXMgY29uZmlybXMgb3VyIGNsYWltIGluIHRoZSBmaXJzdCBwcm9ibGVtIHRoYXQgdGhlIG9wcG9ydHVuaXR5IGZvciB0aGUgc29uJ3Mgam9icyBzZWVtcyB0byBiZSB0aGUgaGlnaGVzdCBpbiBVUywgZm9sbG93ZWQgYnkgVUsgdGhlbiBKYXBhbi4K